// let、const

// 1、let一对{}就是一个作用域，变量不能重复申明、
// 结构赋值：
// 1、数组的结构赋值
// 2、基本类型的结构赋值
// 3、对象的结构赋值
// {	
// 	let a = 1;
// 	var b = 1;
// 	console.log(a)
// }

// console.log(b) //报错
// let b = 1;
// let并不会变量的提前声明

// 
// let [a,b,c] = [1,2,3];
// console.log(a,b,c) //1 2 3

// let [, ,c] = [1,2,3];
// console.log()
// console.log( )
// console.log(c)

// let [x] = [];
// console.log(x) //undefined


// let oBtn = document.querySelectorAll('button');
// let oBtn = document.getElementsByTagName('button');

// for (let i = 0; i < oBtn.length; i++) {
// 	oBtn[i].onclick = function(){
// 		console.log(i)
// 	}
// }


// for (var i = 0; i < oBtn.length; i++) {
// 	oBtn[i].index = i;
// 	oBtn[i].onclick = function(){
// 		console.log(this.index)
// 	}
// }


// for (var i = 0; i < oBtn.length; i++) {
// 	(function(i){
// 		oBtn[i].onclick = function(){
// 			console.log(i)
// 		}
// 	})(i)
// }

// 
// for (let i = 0; i < 4; i++) {
// 	let i = 10;
// 	console.log(i)
// }
// 	console.log(i)


// const A = 10;
// console.log(A)

// const json = {a:1};
// json.a = 100
// console.log(json)

// 对象的结构赋值
// let {b,a} = {a:4,b:5};
// console.log(a)

// let { a: b } = { a: 6 };

// console.log(a)
// console.log(b)

// let  {length:len} = 'maiov';
// console.log(len)
// let { toString: ts } = 1;
// let { toString: bs } = true;

// console.log(ts === Number.prototype.toString) //true
// console.log(bs === Boolean.prototype.toString) //true

// ----------------------------------------------------------------------------------------------------
// 数据结构Set

// 1、如何创建Set
// const s = new Set([1,2,3]);
// console.log(s);

// 2、Set的属性
// console.log(s.size) //3

// 3、方法
// 1、Set.add(value) 添加
// s.add('a').add('b')
// console.log(s)
// 2、set.delete(value)
// console.log(s.delete('a'))  //删除成功true
// console.log(s)
// 3、set.has
// console.log(s.has('a'))
// console.log(s.has('b'))
// 4、clear() 清空
// s.clear()
// console.log(s)
// 5、s.keys()
// 6、s.values()
// console.log(s.keys())
// console.log(s.values())
// 7、entries
// console.log(s.entries())

// 8、forEach()
// s.forEach(function(v,k,set){
// 	console.log(v)
// 	console.log(k)
// })

// 数据结构 Map

// 1、创建一个Map

// const map = new Map([
//     ['a', 1],
//     ['b', 2]
// ]);
// map.set('maio', 'aaa').set('a', 'aaaa').set('hahh', 'hahha')
// console.log(map)


// ----------------------------------------------------------------------------------------------------
// 2、Map 类属性
// map.delete(key)
// map.get(key)
// map.has(key)
// map.clear() //清空
// map.keys() //返回键名

// map.forEach(function(key, value, map) {
//     console.log(key + ':' + value)
// })

// Map注意事项
// map.set(NaN,10).set(NaN,100)
// console.log(map)


// 手写Iterator接口
// const arr = [1, 2, 3];

// // 遍历完成value:undefined.done:true
// function interator(arr) {
//     let index = 0;
//     return {
//         next: function() {
//             return index < arr.length ? { value: arr[index++], done: false } : { value: undefined, done: true }
//         }
//     }
// }

// const it = interator(arr);
// console.log(it.next())
// console.log(it.next())
// console.log(it.next())
// console.log(it.next())

// 凡是有symbol.iterator的属性的数据结构都具有Iterator接口
// const arr = [1, 2, 3];
// const set = new Set(['a', 'b', 'c']);
// const map = new Map([
//     ['a', 1]
// ]);

// const itArr = arr[Symbol.iterator]();
// const itSet = set[Symbol.iterator]();
// const itMap = map[Symbol.iterator]();

// console.log(itArr);
// console.log(itSet);
// console.log(itMap);

// console.log(itSet.next());
// console.log(itSet.next());
// console.log(itSet.next());
// console.log(itSet.next());

// const obj = {};
// console.log(obj[Symbol.iterator])


// 具备iterator接口的数据结构可以进行哪些操作
// 结构赋值
// 扩展运算符 ...

// let [x, y] = set;
// console.log(x, y)

// 扩展运算符 ...
// let str = 'miaov';
// let arrStr = [...str];
// console.log(arrStr) //["m", "i", "a", "o", "v"]


// 数组去重
// const arr2 = [{}, 'a', 'B', 'a', 'B', [], 'c'];
// console.log([...new Set(arr2)]) //[Object, "a", "B", Array(0), "c"]

// for...of循环
// const ofArr = [1, 2, 3, 4, 5];
// for (let i of ofArr) {
//     console.log(i)
// }

// const m = new Map();
// m.set('a', 1).set('b', 2);
// for (let data of m) {
//     console.log(data) //typeof 数组
// }


// for (let [key, value] of m) {
//     console.log(key + ':' + value)
// }



// ----------------------------------------------------------------------------------------------------
// class的基本使用




// ----------------------------------------------------------------------------------------------------
// Symbol
// let s1 = Symbol();
// let s2 = Symbol();
// console.log(s1)
// console.log(s2)


// 可以接收参数，添加描述字符串
// let s1 = Symbol('miaov');
// let s2 = Symbol('zhinengshe');
// console.log(s1)
// console.log(s2)


// Symbol数据类型转换

// console.log(String(Symbol('miaov'))) //Symbol(miaov)
// console.log(Symbol('miaov').toString()) //Symbol(miaov)

// console.log(!!Symbol())  //true

// console.log(Number(Symbol())	//报错，不能转换成数字，不能运算



// ----------------------------------------------------------------------------------------------------
// 函数的扩展

// 函数参数的默认值
// function fn(a = 10,b=20){
// 	console.log(a+b);
// }

// fn();
// fn(0,10);

// rest参数形式（'...变量名'）

// function sum() {
//     var args = arguments;
//     var res = 0;
//     for (var i = 0; i < args.length; i++) {
//         res += args[i];
//     }
//     console.log(res);
// }

// sum(1, 2, 3, 4);


// function sum(...arr) {
// 	console.log(arr)
//     var res = 0;
//     for (var i = 0; i < arr.length; i++) {
//         res += arr[i];
//     }

//     console.log(res);
// }

// sum(1, 2, 3, 4, 5);

// 使用箭头函数 =>

// const fn = a => a;

// const fn2 = function(a) {
//     return a
// }

// const fn = ()=>{

// }

// 多个参数
// const fn = (a, b) => a + b;

// // 多个参数的多行代码
// const fnD = (a, b) => {
//     a = a * 2;
//     b = b * 2;
//     return a + b;
// }

// console.log(fn(1 , 2));
// console.log(fnD(1 , 2));

// 返回一个对象的时候要用()包起来
// const fn = (a,b)=>({a,b});
// console.log(fn(1,2));


// 箭头函数体内没有自己的this对象，使用时，内部this就是定义时所在环境的对象，而不是使用环境

// function fn() {
//     setTimeout(function() {
//         console.log(this)
//     }, 1000);

//     setTimeout(() => {
//         console.log(this)
//     }, 1000)

// }

// var obj = { a: 1 };
// fn.call(obj)

// 不能给箭头函数使用apply、call bind去改变this的指向

// ----------------------------------------------------------------------------------------------------

// Promise
